<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <!-- 
      生命周期
        概念：指的是一个组件从创建到销毁（卸载）的一系列过程。这个过程中Vue内部会做很多的事情：包含有 数据侦听，编译模板，挂载实例到 DOM，以及在数据改变时更新 DOM

      生命周期的钩子函数
        概念：在一个生命周期中，特定的时机会触发的一些函数，就叫做生命周期的钩子函数。

      生命周期的钩子函数有哪些：
        1. 创建阶段
          beforeCreate      创建之前
            1. 数据代理还未完成，不能通过 this 获取到 data、methods、computed 选项中的数据
          created           创建完成
            1. 数据代理已完成，这是可以获取到 data、methods、computed 选项中的数据
            2. 可以在这儿做一些数据初始化的工作。比如给 this 上绑定一些额外的数据
            3. 可以调用后端接口来获取数据
        2. 挂载阶段
          beforeMount       挂载之前
            1. 不能获取真实的DOM
          mounted           挂载完成
            1. 这时，可以获取到真实的DOM
            2. 我们一些第三方的库需要用到真实DOM做初始化的，需要在这儿调用。比如 swiper、echarts、等等
            3. 可以调用后端接口来获取数据，甚至更多时候都推荐在 mounted 来调回初始接口
               1. 如果想让请求更早的发出，可以选择使用 created
               2. 如果为了兼容服务端渲染SSR，就使用 mounted
        3. 更新阶段
          beforeUpdate      更新之前
            1. 获取不到更新之后的最新DOM
          updated           更新完成
            2. 能获取到更新之后的最新DOM
        4. 卸载（销毁）阶段
          beforeUnmount     卸载之前
            1. 都是去干一些清理收尾的工作，一般会选择在这里来做
              1. 之前全局绑定的滚动事件, 要做 remove
              2. 之前设置的计时器，要做 clear
              3. 之前订阅的一些消息来做取消订阅
              ...
          unmounted         卸载完成
            1. 都是去干一些清理收尾的工作
     -->
    <div id="app">
      <h1>生命周期</h1>
      <button @click="count++" id="btn">{{ count }}</button>

      <button @click="fn1">卸载</button>
    </div>

    <script src="../lib/vue-3.js"></script>
    <script>
      const { createApp } = Vue;

      // App组件，也称为 Root 组件
      const App = {
        data() {
          return {
            count: 1,
          };
        },

        computed: {
          dobuleCount() {
            return this.count * 2;
          },
        },

        methods: {
          fn1() {
            // 直接调用 应用实例（app）的 unmount 方法来卸载
            app.unmount();
          },
        },

        beforeCreate() {
          console.log("beforeCreate");
          console.log(this.count);
          console.log(this.dobuleCount);
          console.log(this.fn1);
        },

        created() {
          console.log("created");
          console.log(this.count);
          console.log(this.dobuleCount);
          console.log(this.fn1);
        },

        beforeMount() {
          console.log("beforeMount");
          const btnEl = document.getElementById("btn");
          console.log("btnEl", btnEl); // 能否获取到 btnEl  null
        },

        mounted() {
          console.log("mounted");
          const btnEl = document.getElementById("btn");
          console.log("btnEl", btnEl); // 能否获取到 btnEl  可以
        },

        beforeUpdate() {
          console.log("beforeUpdate");
          const text = document.getElementById("btn").innerHTML;
          console.log("text", text);
        },

        updated() {
          console.log("updated");
          const text = document.getElementById("btn").innerHTML;
          console.log("text", text);
        },

        beforeUnmount() {
          console.log("beforeUnmount");
        },

        unmounted() {
          console.log("unmounted");
        },
      };

      const app = createApp(App);
      // console.log("app", app);

      app.mount("#app");
    </script>
  </body>
</html>
